<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="XiHnv" id="XiHnv"><span data-lake-id="ud4a10561" id="ud4a10561">典型回答</span></h1>
  <p data-lake-id="uf0ac20e4" id="uf0ac20e4"><br></p>
  <p data-lake-id="ua0ae02bf" id="ua0ae02bf"><span data-lake-id="uc2762e21" id="uc2762e21">MySQL的热点数据更新问题，一直都是行业内的一个难题，对于秒杀场景至关重要。一旦处理不好，就可能会导致数据库被打垮。</span></p>
  <p data-lake-id="ue308315b" id="ue308315b"><span data-lake-id="u8f1219de" id="u8f1219de">​</span><br></p>
  <p data-lake-id="u4a4ed9ff" id="u4a4ed9ff"><span data-lake-id="u35165f2b" id="u35165f2b">那么，如果一定要在MySQL这个层面上，抗住高并发的热点数据并发更新，有什么方案呢？拿库存扣减举例</span></p>
  <p data-lake-id="u10eac1b6" id="u10eac1b6"><span data-lake-id="u4ac14b3c" id="u4ac14b3c">​</span><br></p>
  <p data-lake-id="uf7bb5448" id="uf7bb5448"><span data-lake-id="u87c963a3" id="u87c963a3">1、库存拆分，把一个大的库存拆分成多个小库存，拆分后，一次扣减动作就可以分散到不同的库、表中进行，降低锁粒度提升并发。</span></p>
  <p data-lake-id="u3f61c6a2" id="u3f61c6a2" style="text-indent: 2em"><span data-lake-id="u70d64b6a" id="u70d64b6a">优点：实现较简单</span></p>
  <p data-lake-id="u8f5a8a60" id="u8f5a8a60" style="text-indent: 2em"><span data-lake-id="u3522948b" id="u3522948b">缺点：存在碎片问题、库存调控不方便</span></p>
  <p data-lake-id="u1c077637" id="u1c077637"><span data-lake-id="uedcf1062" id="uedcf1062">2、请求合并，把多个库存扣减请求，合并成一个，进行批量更新。</span></p>
  <p data-lake-id="ub4970365" id="ub4970365" style="text-indent: 2em"><span data-lake-id="u1dc89b48" id="u1dc89b48">优点：简单</span></p>
  <p data-lake-id="u40202b0a" id="u40202b0a" style="text-indent: 2em"><span data-lake-id="u1ec9b38e" id="u1ec9b38e">缺点：适用于异步场景，或者经过分析后认为可以合并的场景</span></p>
  <p data-lake-id="u5fa1ea5b" id="u5fa1ea5b"><span data-lake-id="ubcf6231d" id="ubcf6231d">3、把update转换成insert，直接插入一次占用记录，然后异步统计剩余库存，或者通过SQL统计流水方式计算剩余库存。</span></p>
  <p data-lake-id="ud5b403ea" id="ud5b403ea" style="text-indent: 2em"><span data-lake-id="uab75dfc4" id="uab75dfc4">优点：没有update，无锁冲突</span></p>
  <p data-lake-id="ua509dfa0" id="ua509dfa0" style="text-indent: 2em"><span data-lake-id="u3cb015af" id="u3cb015af">缺点：insert时控制不好容易超卖、insert后剩余库存不好统计</span></p>
  <p data-lake-id="u3297c246" id="u3297c246"><br></p>
  <p data-lake-id="uf2f4a145" id="uf2f4a145"><span data-lake-id="u98836964" id="u98836964">除了上面这三个方案外，重点介绍一个我们公司内部在用的，扛了双十一的高并发的秒杀的方案。</span></p>
  <p data-lake-id="u2c692588" id="u2c692588"><span data-lake-id="ufc3463ea" id="ufc3463ea">​</span><br></p>
  <p data-lake-id="u9313e0ba" id="u9313e0ba"><span data-lake-id="ua86383cb" id="ua86383cb">那就是</span><strong><span data-lake-id="u20155d22" id="u20155d22">改造MySQL</span></strong></p>
  <p data-lake-id="u904bbd80" id="u904bbd80"><span data-lake-id="u85a0747f" id="u85a0747f">​</span><br></p>
  <p data-lake-id="u5627ba89" id="u5627ba89"><span data-lake-id="u55d05c64" id="u55d05c64">主要思路就是，针对于频繁更新或秒杀类业务场景，大幅度优化对于热点行数据的update操作的性能。当开启热点更新自动探测时，系统会自动探测是否有单行的热点更新，如果有，则会让大量的并发 update 排队执行，以减少大量行锁造成的并发性能下降。</span></p>
  <p data-lake-id="ufbe77d21" id="ufbe77d21"><span data-lake-id="u024b8efc" id="u024b8efc">​</span><br></p>
  <p data-lake-id="u3e106697" id="u3e106697"><span data-lake-id="u7a05a955" id="u7a05a955">也就是说，他们改造了MySQL数据库，让同一个热点行的更新语句，在执行层进行排队。这样的排队相比update的排队，要轻量级很多，因为他不需要自旋，不需要抢锁。</span></p>
  <p data-lake-id="u20695333" id="u20695333"><span data-lake-id="uee3def5c" id="uee3def5c">​</span><br></p>
  <p data-lake-id="u77b02972" id="u77b02972"><span data-lake-id="u231128df" id="u231128df">这个方案的好处就是开发不需要做额外的事情，只需要开启热点检测就行了。缺点就是改造MySQL数据库有成本。不过现在很多云上数据库都支持了。如：</span></p>
  <p data-lake-id="u00f8ba23" id="u00f8ba23"><span data-lake-id="ua5e0f787" id="ua5e0f787">​</span><br></p>
  <p data-lake-id="ueb18dcff" id="ueb18dcff"><span data-lake-id="uf47d4ac4" id="uf47d4ac4">腾讯云数据库MySQL热点更新： </span><a href="https://cloud.tencent.com/document/product/236/63239" target="_blank" data-lake-id="ub4e9fa20" id="ub4e9fa20"><span data-lake-id="u77d8b121" id="u77d8b121">https://cloud.tencent.com/document/product/236/63239</span></a></p>
  <p data-lake-id="u32a80f92" id="u32a80f92"><span data-lake-id="u083073c9" id="u083073c9">阿里云数据库Inventory Hint： </span><a href="https://www.alibabacloud.com/help/zh/apsaradb-for-rds/latest/inventory-hint" target="_blank" data-lake-id="u0e4ec6cf" id="u0e4ec6cf"><span data-lake-id="u61ac987a" id="u61ac987a">https://www.alibabacloud.com/help/zh/apsaradb-for-rds/latest/inventory-hint</span></a></p>
  <p data-lake-id="u6a26f6a0" id="u6a26f6a0"><span data-lake-id="ua4b47d06" id="ua4b47d06">​</span><br></p>
  <p data-lake-id="u6e904e4d" id="u6e904e4d"><span data-lake-id="u2d95b82a" id="u2d95b82a">​</span><br></p>
  <p data-lake-id="u9046d4d5" id="u9046d4d5"><span data-lake-id="u28b8aecf" id="u28b8aecf">具体原理见：</span></p>
  <p data-lake-id="u8e0502e0" id="u8e0502e0"><span data-lake-id="u64d205e2" id="u64d205e2">​</span><br></p>
  <p data-lake-id="u1a2aa3c0" id="u1a2aa3c0"><br></p>
 </body>
</html>